package com.quectel.aiot.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.quectel.aiot.entity.Role;
// ========== 1. 导入新增的 DeviceService ==========
import com.quectel.aiot.service.DeviceService;
import com.quectel.aiot.entity.Device; // 1. 导入新增的 Device 实体类
import com.quectel.aiot.service.RoleService;
// ========== 2. 导入新增的 VoiceService 和 Voice 实体 ==========
import com.quectel.aiot.service.VoiceService;
import com.quectel.aiot.entity.Voice;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

// ... 其他 import 保持不变 ...
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;


@RestController
@Api(tags = "授权管理", description = "授权相关接口")
public class AuthorizationController {

    private static final String AK = "ALTAKuH73Ca55dg7FBfA91EGNF";
    private static final String SK = "a9bb472c969c4b40a91347340984b0ca";
    private static final String METHOD = "POST";
    private static final String URI = "/api/v1/aiagent/generateAIAgentCall";
    private static final String QUERY = "";
    private static final String HOST = "rtc-aiagent.baidubce.com";
    private static final String API_URL = "https://rtc-aiagent.baidubce.com/api/v1/aiagent/generateAIAgentCall";

    @Autowired
    private RoleService roleService;

    // ========== 2. 注入我们新增的 DeviceService ==========
    @Autowired
    private DeviceService deviceService;

    // ========== 3. 注入新增的 VoiceService ==========
    @Autowired
    private VoiceService voiceService;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 获取当前时间戳（BCE格式，ISO 8601 UTC）
     * (此方法无需修改)
     */
    private String getCurrentBceDate() {
        return ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
    }

    /**
     * 从数据库获取角色配置（结合voice配置）
     * 修改后的方法，同时处理role_id和voice_id
     */
    private Map<String, Object> getRoleConfigWithVoice(String roleId, Long voiceId) {
        try {
            System.out.println("正在查询角色ID: " + roleId + ", 语音ID: " + voiceId);
            
            // 1. 获取角色配置
            Role role = roleService.getRoleById(Long.parseLong(roleId));
            if (role == null) {
                System.out.println("未找到角色记录，ID: " + roleId);
                return null;
            }
            System.out.println("找到角色记录: " + role.getName() + ", app_id: " + role.getAppId());
            
            // 2. 获取语音配置（如果voiceId不为空）
            Voice voice = null;
            if (voiceId != null) {
                voice = voiceService.getVoiceById(voiceId);
                if (voice != null) {
                    System.out.println("找到语音记录: " + voice.getName() + ", tts: " + voice.getTts());
                } else {
                    System.out.println("未找到语音记录，ID: " + voiceId);
                }
            }
            
            // 3. 构建基础配置（来自role表）
            Map<String, Object> config = new HashMap<>();
            config.put("location", role.getLocation() != null ? role.getLocation() : "");
            config.put("role", role.getRole() != null ? role.getRole() : "");
            config.put("sceneRole", role.getSceneRole() != null ? role.getSceneRole() : "");
            config.put("tts_sayhi", role.getTtsSayhi() != null ? role.getTtsSayhi() : "");
            config.put("lang", role.getLang() != null ? role.getLang() : "zh");
            config.put("disable_voice_auto_int", role.getDisableVoiceAutoInt() != null ? role.getDisableVoiceAutoInt() : false);
            config.put("llm", role.getLlm() != null ? role.getLlm() : "");
            config.put("llm_url", role.getLlmUrl() != null ? role.getLlmUrl() : "");
            config.put("llm_cfg", role.getLlmCfg() != null ? role.getLlmCfg() : "");
            config.put("llm_token", role.getLlmToken() != null ? role.getLlmToken() : "");
            
            // 4. 处理TTS配置（只使用tts和tts_url字段）
            String ttsConfig = "DEFAULT";
            String ttsUrl = "";
            String audiocodec = "opus";
            
            if (voice != null) {
                // 获取voice表中的配置
                ttsConfig = voice.getTts() != null ? voice.getTts() : "DEFAULT";
                ttsUrl = voice.getTtsUrl() != null ? voice.getTtsUrl() : "";
                audiocodec = voice.getAudiocodec() != null ? voice.getAudiocodec() : "opus";
                
                // 如果tts_url不为空，直接使用
                if (ttsUrl != null && !ttsUrl.trim().isEmpty()) {
                    System.out.println("使用voice表中的TTS配置: " + ttsUrl);
                } else {
                    // tts_url为空，根据tts字段决定使用什么配置
                    if ("CUSTOM".equals(ttsConfig)) {
                        // 自定义配置但tts_url为空，使用默认配置
                        ttsConfig = "DEFAULT";
                        ttsUrl = "DEFAULT{\"vcn\": \"4103\",\"vol\": 0.1,\"spd\": 1.1}";
                        System.out.println("自定义配置但tts_url为空，使用默认语音配置: " + ttsUrl);
                    } else {
                        // 使用默认配置
                        ttsUrl = "DEFAULT{\"vcn\": \"4103\",\"vol\": 0.1,\"spd\": 1.1}";
                        System.out.println("使用默认语音配置: " + ttsUrl);
                    }
                }
            } else {
                // 没有voice配置，使用默认值
                ttsConfig = "DEFAULT";
                ttsUrl = "DEFAULT{\"vcn\": \"4103\",\"vol\": 0.1,\"spd\": 1.1}";
                System.out.println("没有voice配置，使用默认语音配置: " + ttsUrl);
            }
            
            config.put("tts", ttsConfig);
            config.put("tts_url", ttsUrl);
            config.put("audiocodec", audiocodec);
            
            // 5. 构建最终结果
            Map<String, Object> result = new HashMap<>();
            result.put("app_id", role.getAppId());
            result.put("config", config);
            System.out.println("构建的配置: " + result);
            return result;
        } catch (Exception e) {
            System.err.println("查询角色配置时发生错误: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    // =================================================================
    // ===========   修改获取对话实例接口的核心逻辑 (最终版)   ============
    // =================================================================
    @PostMapping("/get-conversation-instance")
    @ApiOperation(value = "获取对话实例", notes = "根据PK和DK获取对话实例配置并调用百度云API")
    public ResponseEntity<Object> getConversationInstance(
            @ApiParam(name = "requestBody", value = "请求体，包含pk和dk字段", required = true)
            @RequestBody String requestBody) {
        try {
            System.out.println("收到请求体: " + requestBody);

            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(requestBody);

            String pk = jsonNode.has("pk") ? jsonNode.get("pk").asText() : null;
            String dk = jsonNode.has("dk") ? jsonNode.get("dk").asText() : null;

            if (pk == null || pk.isEmpty() || dk == null || dk.isEmpty()) {
                return ResponseEntity.badRequest().body("缺少必要参数: pk 和 dk");
            }

            // 1. 调用新的 Service 方法，直接获取包含 roleId 和 voiceId 的完整 Device 对象
            Device device = deviceService.getDeviceWithCurrentRole(pk, dk);

            // 2. 检查设备是否存在，以及设备是否已设置当前角色
            if (device == null || device.getRoleId() == null) {
                return ResponseEntity.status(404).body("设备未找到或未设置当前角色。");
            }

            // 3. 从 Device 对象中提取 role_id 和 voice_id
            String roleId = String.valueOf(device.getRoleId());
            Long voiceId = device.getVoiceId(); // 现在使用voiceId

            // 4. 使用获取到的 roleId 和 voiceId 来获取完整的配置
            Map<String, Object> roleConfig = getRoleConfigWithVoice(roleId, voiceId);
            if (roleConfig == null) {
                return ResponseEntity.status(404).body("角色ID '" + roleId + "' 不存在或配置不完整");
            }

            System.out.println("成功获取角色配置: " + roleConfig);


            // E. 后续的认证和API调用逻辑完全不变
            Map<String, String> authHeaders = generateAuthorizationHeadersCorrect();
            Map<String, Object> requestData = new HashMap<>();
            requestData.put("app_id", roleConfig.get("app_id"));
            requestData.put("config", objectMapper.writeValueAsString(roleConfig.get("config")));

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            headers.set("Authorization", authHeaders.get("Authorization"));
            headers.set("x-bce-date", authHeaders.get("x-bce-date"));
            headers.set("Host", HOST);

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestData, headers);

            System.out.println("准备调用百度云API: " + API_URL);

            ResponseEntity<String> response = restTemplate.exchange(
                    API_URL, HttpMethod.POST, entity, String.class);

            System.out.println("百度云API响应状态码: " + response.getStatusCode());
            System.out.println("百度云API响应内容: " + response.getBody());

            if (response.getStatusCode().is2xxSuccessful()) {
                return ResponseEntity.ok(objectMapper.readTree(response.getBody()));
            } else {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("error", "API请求失败");
                errorResponse.put("status_code", response.getStatusCode().value());
                errorResponse.put("response", response.getBody());
                return ResponseEntity.status(response.getStatusCode()).body(errorResponse);
            }

        } catch (org.springframework.web.client.HttpClientErrorException e) {
            System.err.println("HTTP客户端错误: " + e.getMessage());
            System.err.println("响应状态码: " + e.getStatusCode().value());
            System.err.println("响应体: " + e.getResponseBodyAsString());
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("error", "API请求失败");
            errorResponse.put("status_code", e.getStatusCode().value());
            errorResponse.put("response", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(errorResponse);
        } catch (Exception e) {
            System.err.println("服务器内部错误: " + e.getMessage());
            e.printStackTrace();
            return ResponseEntity.status(500).body("服务器内部错误: " + e.getMessage());
        }
    }

    /**
     * 从数据库获取角色配置（保持向后兼容）
     * 此方法仅用于generate-authorization接口
     */
    private Map<String, Object> getRoleConfig(String roleId) {
        // 调用新的方法，传入null作为voiceId
        return getRoleConfigWithVoice(roleId, null);
    }

    /**
     * 生成百度云API认证头 - 使用正确的签名流程
     * (此方法无需修改)
     */
    private Map<String, String> generateAuthorizationHeadersCorrect() throws Exception {
        // ... 此方法内部逻辑完全不变 ...
        String xBceDate = getCurrentBceDate();
        Map<String, String> header = new TreeMap<>();
        header.put("Host", HOST);
        header.put("x-bce-date", xBceDate);
        String signedHeaders = "host;x-bce-date";
        String authStringPrefix = String.format("bce-auth-v1/%s/%s/1800", AK, xBceDate);
        String canonicalURI = encodeURI(URI);
        String canonicalQueryString = QUERY;
        java.util.List<String> headerList = new ArrayList<>();
        for (Map.Entry<String, String> entry : header.entrySet()) {
            String key = URLEncoder.encode(entry.getKey().toLowerCase(), "UTF-8");
            String value = URLEncoder.encode(entry.getValue(), "UTF-8");
            headerList.add(key + ":" + value);
        }
        Collections.sort(headerList);
        String canonicalHeaders = String.join("\n", headerList);
        String canonicalRequest = String.format("%s\n%s\n%s\n%s", METHOD, canonicalURI, canonicalQueryString, canonicalHeaders);
        byte[] signingKey = hmacSha256(SK.getBytes(StandardCharsets.UTF_8), authStringPrefix.getBytes(StandardCharsets.UTF_8));
        String signingKeyHex = bytesToHex(signingKey);
        byte[] signature = hmacSha256(signingKeyHex.getBytes(StandardCharsets.UTF_8), canonicalRequest.getBytes(StandardCharsets.UTF_8));
        String signatureHex = bytesToHex(signature);
        String authorization = String.format("%s/%s/%s", authStringPrefix, signedHeaders, signatureHex);
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", authorization);
        headers.put("x-bce-date", xBceDate);
        headers.put("Host", HOST);
        return headers;
    }

    // --- 其他辅助方法无需修改 ---

    @PostMapping("/generate-authorization")
    @ApiOperation(value = "生成授权信息", notes = "生成百度云API认证信息")
    public ResponseEntity<Object> generateAuthorization() {
        // ... 此方法无需修改 ...
        try {
            Map<String, String> authHeaders = generateAuthorizationHeadersCorrect();
            Map<String, String> result = new HashMap<>();
            result.put("authorization", authHeaders.get("Authorization"));
            result.put("x_bce_date", authHeaders.get("x-bce-date"));
            result.put("host", HOST);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            System.err.println("生成授权信息错误: " + e.getMessage());
            e.printStackTrace();
            return ResponseEntity.status(500).body("服务器内部错误: " + e.getMessage());
        }
    }

    private byte[] hmacSha256(byte[] key, byte[] data) throws NoSuchAlgorithmException, InvalidKeyException {
        // ... 此方法无需修改 ...
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");
        mac.init(secretKeySpec);
        return mac.doFinal(data);
    }

    private String bytesToHex(byte[] bytes) {
        // ... 此方法无需修改 ...
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append("0");
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    private String encodeURI(String uri) {
        // ... 此方法无需修改 ...
        StringBuilder sb = new StringBuilder();
        for (char c : uri.toCharArray()) {
            if (c == '/') {
                sb.append(c);
            } else {
                try {
                    sb.append(URLEncoder.encode(String.valueOf(c), "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    sb.append(c);
                }
            }
        }
        return sb.toString();
    }
}